home *** CD-ROM | disk | FTP | other *** search
- /*================================================================================
- TEUtilities.c
-
- ©1991 Greg Anderson
- greggor@apple.com
-
- FREE DISTRIBUTION
-
- The possessor of this source code may use any portion of
- it for any purpose, and I place no restriction on its
- redistribution.
-
- Useful routines to use with TextEdit.
-
- These routines support VERTICAL scrollbars only. Horizontal
- scrollbars are left as an exercise for the reader.
-
- ================================================================================*/
- #include <stdio.h>
- #include <string.h>
- #include <Types.h>
- #include <Resources.h>
- #include <pascal.h>
-
- #include "TEUtilities.h"
-
- #ifndef __MEMORY__
- #include "Memory.h"
- #endif
-
- short TELineHeight( TEHandle te );
-
- /*----------------------------------------------------------------------
- Get the current selection
- ----------------------------------------------------------------------*/
- void TEGetSelect( short* selStart, short* selEnd, TEHandle te )
- {
- *selStart = (*te)->selStart;
- *selEnd = (*te)->selEnd;
- }
-
- /*----------------------------------------------------------------------
- Get some characters from the textedit record
- ----------------------------------------------------------------------*/
- void TEGetChars( char* buf, short from, short to, TEHandle te )
- {
- CharsHandle theText;
- short theState;
- unsigned char* ptr;
-
- theText = TEGetText(te);
- theState = HGetState( (Handle)theText );
- HLock( (Handle)theText );
- ptr = (unsigned char*)(*theText);
- ptr += from;
- BlockMove( ptr, buf, to - from );
- buf[to - from] = 0;
- HSetState( (Handle)theText, theState );
- }
-
- /*----------------------------------------------------------------------
- Return the current view rectangle of the given textedit record
- ----------------------------------------------------------------------*/
- void GetTEView( TEHandle te, Rect* viewRect )
- {
- *viewRect = (*te)->viewRect;
- }
-
- /*----------------------------------------------------------------------
- Return the number of lines in the current textedit buffer
- ----------------------------------------------------------------------*/
- short TELines( TEHandle te )
- {
- return( (*te)->nLines );
- }
-
- /*----------------------------------------------------------------------
- Return the pixel height of the current textedit buffer
- ----------------------------------------------------------------------*/
- short TEHeight( TEHandle te )
- {
- return TEGetHeight( TELines(te), 0, te );
-
- #if 0
- return TELines(te) * (*te)->lineHeight;
- #endif
- }
-
- /*----------------------------------------------------------------------
- Return the # of pixels in one line
- ----------------------------------------------------------------------*/
- short TELineHeight( TEHandle te )
- {
- if( (*te)->lineHeight == -1 )
- return 16;
-
- return (*te)->lineHeight;
- }
-
- /*----------------------------------------------------------------------
- Return the # of pixels to the current scroll location
- ----------------------------------------------------------------------*/
- short GetTEVScroll( TEHandle te )
- {
- return (*te)->viewRect.top - (*te)->destRect.top;
- }
-
- /*----------------------------------------------------------------------
- Return the pixel height of the view rectangle
- ----------------------------------------------------------------------*/
- short ViewHeight( TEHandle te )
- {
- Rect viewRect;
-
- GetTEView( te , &viewRect );
-
- return viewRect.bottom - viewRect.top;
- }
-
- /*----------------------------------------------------------------------
- Return a number from 1 - 1000 indicating the current scroll location of
- the textedit record
- ----------------------------------------------------------------------*/
- short VScrollLocation( TEHandle te )
- {
- long tmp;
-
- tmp = GetTEVScroll(te) * 1000L;
- tmp /= (TEHeight(te) - ViewHeight(te));
-
- return tmp;
- }
-
- /*----------------------------------------------------------------------
- Call TEScroll, but don't scroll past top or below bottom
-
- This code also adjusts the scrollbar.
- ----------------------------------------------------------------------*/
- void PinnedTEVScroll( TEHandle te, ControlHandle scrollbar, short dv )
- {
- short max;
- short lineh = TELineHeight(te);
-
- if( lineh == -1 )
- lineh = 16;
-
- if( dv > 0 )
- {
- max = GetTEVScroll(te);
- if( dv > max )
- dv = max;
- }
- else
- {
- max = TEHeight(te) - ViewHeight(te) - GetTEVScroll(te) - 1;
- max = max - (max % lineh) + lineh;
- if( max < 0 )
- max = 0;
- if( (-dv) > max )
- dv = -max;
- }
- TEScroll(0,dv,te);
- FixScrollBar( scrollbar );
- }
-
- /*----------------------------------------------------------------------
- Scroll directly to a new location.
- ----------------------------------------------------------------------*/
- void TEVThumbScroll( TEHandle te, ControlHandle scrollbar )
- {
- long newScroll;
- short deltaScroll;
-
- /*
- // 'GetCtlValue' ranges from 0 to 1000. Convert this into a textedit range
- // of zero to (texteditHeight - viewHeight)
- */
- newScroll = GetCtlValue( scrollbar );
- newScroll *= (TEHeight(te) - ViewHeight(te));
- newScroll /= 1000;
- /*
- // We don't want to scroll to just any pixel, though...
- */
- newScroll /= TELineHeight(te);
- newScroll *= TELineHeight(te);
- /*
- // Now find out where we are, and how far we have to move to get to
- // where we want to go.
- */
- deltaScroll = GetTEVScroll(te) - newScroll;
- PinnedTEVScroll( te, scrollbar, deltaScroll );
- }
-
- /*----------------------------------------------------------------------
- Scroll up or down one line
- ----------------------------------------------------------------------*/
- void ScrollTELine( TEHandle te, ControlHandle scrollbar, short dir )
- {
- PinnedTEVScroll( te, scrollbar, dir * TELineHeight(te) );
- }
-
- /*----------------------------------------------------------------------
- Scroll up or down one page
- ----------------------------------------------------------------------*/
- void ScrollTEPage( TEHandle te, ControlHandle scrollbar, short dir )
- {
- short linePix;
- short pagePix;
- short pageLines;
-
- pagePix = ViewHeight(te);
- linePix = TELineHeight(te);
- pageLines = pagePix / linePix;
- pagePix = (pageLines - 1) * linePix;
-
- PinnedTEVScroll( te, scrollbar, dir * pagePix );
- }
-
- /*----------------------------------------------------------------------
- This routine is called repeatedly while the scroll bar is tracked.
- ----------------------------------------------------------------------*/
- pascal TrackUpDownArrows( ControlHandle theControl, short partCode)
- {
- TEHandle te = (TEHandle)GetCRefCon(theControl);
-
- switch( partCode )
- {
- case inUpButton:
- {
- ScrollTELine( te, theControl, 1 );
- break;
- }
-
- case inDownButton:
- {
- ScrollTELine( te, theControl, -1 );
- break;
- }
- }
- }
-
- /*----------------------------------------------------------------------
- Interact with a VERTICAL scroll bar
-
- Pass a handle to the scrollbar's control record and the point (in LOCAL
- coordinates) where the mouse hit the scrollbar.
-
- WARNING: The refCon of the scrollbar MUST point to the textedit record
- That it is associated with.
- ----------------------------------------------------------------------*/
- void ScrollBarClick( ControlHandle scrollbar, Point where )
- {
- TEHandle te;
- int value;
-
- /*
- // Ponnuki always sets the refCon of a scrollbar to the
- // TEHandle associated with that scrollbar
- */
- te = (TEHandle) GetCRefCon( scrollbar );
- /*
- // TrackControl passes different parameters to 'trackAction' based on
- // what type of control it is tracking & what part of the control the
- // mouse is in. Therefore, we cannot simply use the same trackAction
- // procedure for every 'TrackControl' that might come through this
- // routine. :< Fortunately, we only need to call a 'trackAction'
- // proc for the up and down facing buttons.
- */
- switch( TestControl(scrollbar,where) )
- {
- case inUpButton:
- case inDownButton:
- {
- TrackControl(scrollbar,where,(ProcPtr)TrackUpDownArrows);
- break;
- }
-
- case inPageUp:
- case inPageDown:
- case inThumb:
- {
- switch( TrackControl(scrollbar,where,(ProcPtr)0L) )
- {
- case inPageUp:
- {
- ScrollTEPage( te, scrollbar, 1 );
- break;
- }
-
- case inPageDown:
- {
- ScrollTEPage( te, scrollbar, -1 );
- break;
- }
-
- case inThumb:
- {
- TEVThumbScroll( te, scrollbar );
- break;
- }
- }
- break;
- }
- }
- }
-
- /*----------------------------------------------------------------------
- Fix a VERTICAL scroll bar after a TE field has been scrolled
-
- Pass a handle to the scrollbar's control record
-
- WARNING: The refCon of the scrollbar MUST point to the textedit record
- That it is associated with.
- ----------------------------------------------------------------------*/
- void FixScrollBar( ControlHandle scrollbar )
- {
- TEHandle te;
- int value;
-
- /*
- // Ponnuki always sets the refCon of a scrollbar to the
- // TEHandle associated with that scrollbar
- */
- te = (TEHandle) GetCRefCon( scrollbar );
- SetCtlValue( scrollbar, VScrollLocation(te) );
- Draw1Control(scrollbar);
- }
-